import { PureComponent } from 'react';
import {Button, Card, Col, Form, Image, Input, message, Row, Upload, Modal, Select} from 'antd';
import React from 'react';
import {SaveFilled, RollbackOutlined, LoadingOutlined, PlusOutlined, EditOutlined } from '@ant-design/icons';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import { hasPermission, nopermission } from "@/hasPermission";
import { connect } from "umi";
import { history } from "@@/core/history";
import {getCurrentUser} from "@/utils/globalService";
import Quill from 'quill';
import 'react-quill/dist/quill.core.css';
import QuillEmoji from 'quill-emoji';
import 'quill-emoji/dist/quill-emoji.css';
import {queryByCode} from "@/pages/BlogEdit/service";
const { Option } = Select;

const reg = /,$/gi;

function beforeUpload(file) {
  if (!hasPermission('user:update')){
    nopermission();
    return false;
  }
  let isImage = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif';
  if (!isImage) {
    message.error('请选择jpg或png格式的文件!');
    return false;
  }
  let isst10M = file.size / 1024 / 1024 < 10;
  if (!isst10M) {
    message.error('文件过大！请重新上传');
  }
  const isNotEmpty = file.size > 0;
  if (!isNotEmpty) {
    message.error('文件为空！请重新上传');
  }
  return isImage && isst10M && isNotEmpty;
}

class BlogEdit extends PureComponent {

  constructor(props) {
    super(props);
    this.state = {
      value: '',
      fileList: [],
      imgFileList: [],
      num: 0,
      imgNum: 0,
      cover: null,
      coverLoading: false,
      imgLoading: false,
      previewVisible: false,
      previewTitle: '',
      previewImgVisible: false,
      previewImgTitle: '',
      currentUser: null,
      imgHandlerVisible: false,
      img: null,
      blogType: null,
      blogLabel: null
    };
  }

  componentDidMount() {
    getCurrentUser().then(res => {
      if (res.status == 200){
        this.setState({ currentUser: res.data });
      }
    });
    queryByCode({ code: 'blogLabel' }).then(res => {
      if (res.status == 200){
        this.setState({ blogLabel: res.data.value });
      }
    })
    queryByCode({ code: 'blogType' }).then(res => {
      if (res.status == 200){
        this.setState({ blogType: res.data.value });
      }
    })
    this.formRef = React.createRef();
    this.quillRef = React.createRef();
    Quill.register({
      'modules/emoji-toolbar': QuillEmoji.ToolbarEmoji,
      'modules/emoji-textarea': QuillEmoji.TextAreaEmoji,
      'modules/emoji-shortname': QuillEmoji.ShortNameEmoji
    })
  }

  onValueChange = (value) => {
    this.setState({
      value
    })
  }

  handleChange = info => {
    const { avatarKey, num } = this.state;
    const fileList = info.fileList;
    this.setState({ fileList: fileList });
    if (info.file.status == 'uploading' && num == 0){
      this.setState({
        num: 1,
        coverLoading: true
      });
    }
    if (info.file.status === 'done') {
      let res = info.file.response;
      if (res.status == 200){
        message.success({ content: '上传成功！', avatarKey, duration: 2 });
        this.setState({cover: res.data});
      }else {
        message.error({ content: res.message, avatarKey, duration: 2 });
      }
      this.setState({
        num: 0,
        coverLoading: false
      });
    }
  }

  handleImgChange = info => {
    const { avatarKey, imgNum } = this.state;
    const fileList = info.fileList;
    this.setState({ imgFileList: fileList });
    if (info.file.status == 'uploading' && imgNum == 0){
      this.setState({
        num: 1,
        imgLoading: true
      });
    }
    if (info.file.status === 'done') {
      let res = info.file.response;
      if (res.status == 200){
        message.success({ content: '上传成功！', avatarKey, duration: 2 });
        this.setState({ img: res.data });
      }else {
        message.error({ content: res.message, avatarKey, duration: 2 });
      }
      this.setState({
        imgNum: 0,
        imgLoading: false
      });
    }
  }

  handlePreview = async file => {
    this.setState({
      previewVisible: true,
      previewTitle: file.name || file.url.substring(file.url.lastIndexOf('/') + 1),
    });
  };

  handleImgPreview = async file => {
    this.setState({
      previewImgVisible: true,
      previewImgTitle: file.name || file.url.substring(file.url.lastIndexOf('/') + 1),
    });
  };

  handleCancel = () => this.setState({ previewVisible: false });

  imgCancel = () => this.setState({ previewImgVisible: false });

  handleImgCancel = () => this.setState({ imgHandlerVisible: false });

  toBlogInfo = (id) => {
    history.push('/blogInfo?id=' + id);
  };

  handleSave = () => {
    if (!hasPermission('user:update')){
      nopermission();
      return;
    }
    const { dispatch } = this.props;
    const { currentUser } = this.state;
    let values;
    try {
      values = this.formRef.current.getFieldsValue();
    }catch (e) {
      message.error('带*的为必填项！');
      return ;
    }
    if (values.title == null || values.subTitle == null || values.label == null
      || values.type == null || this.state.value == null){
      message.error('带*的为必填项！');
      return ;
    }
    if (values.title.length > 100 || values.subTitle.length > 100){
      message.info('标题或子标题长度超过限制！');
      return ;
    }
    const hide = message.loading('保存中..', 0);
    let url = values.id ? 'blogEdit/update' : 'blogEdit/add';
    let label = '', type = '';
    if (values.label && values.label.length > 0){
      values.label.map((item) => label += item + ',');
      label = label.replace(reg, "");
    }
    if (values.type && values.type.length > 0){
      values.type.map((item) => type += item + ',');
      type = type.replace(reg, "");
    }
    dispatch({
      type: url,
      payload: {
        userId: currentUser && currentUser.id,
        title: values.title,
        subTitle: values.subTitle,
        cover: this.state.cover || '',
        label: label,
        type: type,
        content: this.state.value
      }
    }).then(res => {
      if (res.status == 200){
        message.success('保存成功！');
        this.toBlogInfo(res.data.id);
      }else {
        message.error('保存失败！');
      }
      setTimeout(hide, 50);
    })
  };

  goBack = () => {
    history.go(-1);
  };

  imageHandler = () => {
    this.setState({ imgHandlerVisible: true });
  };

  insertImg = () => {
    const { img } = this.state;
    this.quillEditor = this.quillRef.getEditor();
    let index = this.quillEditor.getSelection() ? this.quillEditor.getSelection().index : this.quillEditor.selection.savedRange.index;
    try {
      this.quillEditor.insertEmbed(index, 'image', img);
    }catch (e){
      message.error('插入图片错误！');
    }
    this.handleImgCancel();
  }

  render() {
    const {
      value, coverLoading, imgFileList, imgLoading, previewImgVisible, previewImgTitle,
      fileList, cover, img, previewVisible, previewTitle, currentUser, imgHandlerVisible,
      blogLabel, blogType
    } = this.state;
    const uploadButton = <div>
      {coverLoading ? <LoadingOutlined /> : <PlusOutlined />}
      <div style={{ marginTop: 8 }}>上传</div>
    </div>
    const uploadImgButton = <div>
      {imgLoading ? <LoadingOutlined /> : <PlusOutlined />}
      <div style={{ marginTop: 8 }}>上传</div>
    </div>

    const modules = {
      toolbar: [
        ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
        ['blockquote', 'code-block'],
        ['link', 'image'],

        [{ 'header': 1 }, { 'header': 2 }],               // custom button values
        [{ 'list': 'ordered' }, { 'list': 'bullet' }],
        [{ 'script': 'sub' }, { 'script': 'super' }],      // superscript/subscript
        [{ 'indent': '-1' }, { 'indent': '+1' }],          // outdent/indent
        [{ 'direction': 'rtl' }],                         // text direction

        // [{ 'size': ['small', false, 'large', 'huge'] }],  // custom dropdown
        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

        [{ 'color': [] }, { 'background': [] }],          // dropdown with defaults from theme
        [{ 'font': [] }],
        [{ 'align': [] }],

        ['clean']                                         // remove formatting button
      ]
    }

    const toolbarContainer = [
      [{ 'size': ['small', false, 'large', 'huge'] }],
      [{ 'font': [] }],
      [{ 'header': 1 }, { 'header': 2 }],
      ['bold', 'italic', 'underline', 'strike'],
      [{ 'align': [] }],
      [{ 'indent': '-1' }, { 'indent': '+1' }],
      [{ 'direction': 'rtl' }],
      [{ 'script': 'sub' }, { 'script': 'super' }],
      ['blockquote', 'code-block'],
      [{ 'list': 'ordered' }, { 'list': 'bullet' }],
      [{ 'color': [] }, { 'background': [] }],
      ['emoji', 'image', 'video', 'link'],
      ['clean']
    ]

    return (
      <>
        <Card
          bordered={false}
          title={<><EditOutlined />&nbsp;新增博客</>}
          actions={[
            <Button shape='round' type='primary' icon={<SaveFilled />} onClick={this.handleSave}>保存</Button>,
            <Button shape='round' type='ghost' icon={<RollbackOutlined />} onClick={this.goBack}>返回</Button>
          ]}
        >
          <Form ref={this.formRef} labelCol={{ span: 3 }} wrapperCol={{ span: 16 }}>
            <Row>
              <Col span={12}>
                <Form.Item label='标题' name='title' rules={[{ required: true, message: '标题不能为空' }]}>
                  <Input style={{ width: '150%' }} allowClear maxLength={20}/>
                </Form.Item>
              </Col>
            </Row>
            <Row>
              <Col span={12}>
                <Form.Item label='子标题' name='subTitle' rules={[{ required: true, message: '子标题不能为空' }]}>
                  <Input style={{ width: '150%' }} allowClear maxLength={30}/>
                </Form.Item>
              </Col>
            </Row>
            <Row>
              <Col span={12}>
                <Form.Item label='封面背景' name='cover'>
                  <Upload
                    name='file'
                    action='joker/minio/uploadTemporary'
                    listType="picture-card"
                    fileList={fileList}
                    accept='image/*'
                    maxCount={1}
                    data={{
                      id: currentUser && currentUser.id
                    }}
                    headers={{
                      Authorization: 'Bearer ' + localStorage.getItem('token'),
                    }}
                    beforeUpload={beforeUpload.bind(this)}
                    onChange={this.handleChange.bind(this)}
                    onPreview={this.handlePreview}
                  >
                    {uploadButton}
                  </Upload>
                </Form.Item>
              </Col>
            </Row>
            <Row>
              <Col span={12}>
                <Form.Item label='标签' name='label' rules={[{ required: true, message: '标签不能为空' }]}>
                  <Select mode="tags" style={{ width: '150%' }}>
                    {blogLabel && blogLabel.split(',').map((item) => <Option key={item}>{item}</Option>)}
                  </Select>
                </Form.Item>
              </Col>
            </Row>
            <Row>
              <Col span={12}>
                <Form.Item label='分类' name='type' rules={[{ required: true, message: '分类不能为空' }]}>
                  <Select mode="tags" style={{ width: '150%' }}>
                    {blogType && blogType.split(',').map((item) => <Option key={item}>{item}</Option>)}
                  </Select>
                </Form.Item>
              </Col>
            </Row>
            <Row>
              <Col span={12}>
                <Form.Item label='内容' rules={[{ required: true, message: '内容不能为空' }]}>
                  <ReactQuill
                    ref={ref => this.quillRef = ref}
                    value={value}
                    theme="snow"
                    modules={{
                      toolbar: {
                        container: toolbarContainer,
                        handlers: {
                          image: this.imageHandler
                        }
                      },
                      'emoji-toolbar': true,
                      'emoji-textarea': true,
                      'emoji-shortname': true,
                    }}
                    onChange={this.onValueChange}
                    style={{ width: '250%' }}
                  />
                </Form.Item>
              </Col>
            </Row>
          </Form>
        </Card>
        <Modal
          visible={previewVisible}
          title={previewTitle}
          footer={null}
          onCancel={this.handleCancel}
        >
          <Image alt="封面" style={{ width: '100%' }} src={cover} />
        </Modal>
        <Modal
          visible={previewImgVisible}
          title={previewImgTitle}
          footer={null}
          onCancel={this.imgCancel}
        >
          <Image alt="图片" style={{ width: '100%' }} src={img} />
        </Modal>
        <Modal
          visible={imgHandlerVisible}
          title='图片上传'
          onCancel={this.handleImgCancel}
          onOk={this.insertImg}
        >
          <Row>
            <Col span={24}>
              <Upload
                name='file'
                action='joker/minio/uploadTemporary'
                listType="picture-card"
                fileList={imgFileList}
                accept='image/*'
                maxCount={1}
                data={{
                  id: currentUser && currentUser.id
                }}
                headers={{
                  Authorization: 'Bearer ' + localStorage.getItem('token'),
                }}
                beforeUpload={beforeUpload.bind(this)}
                onChange={this.handleImgChange.bind(this)}
                onPreview={this.handleImgPreview}
              >
                {uploadImgButton}
              </Upload>
            </Col>
          </Row>
        </Modal>
      </>
    );
  }
}

export default connect(({ blogEdit }) => ({
  blogEdit
}))(BlogEdit);
